package com.xianan.xuhui.netsecurityproject.service.web.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xianan.xuhui.netsecurityproject.domain.dto.login.LoginInputDto;
import com.xianan.xuhui.netsecurityproject.domain.dto.login.LoginResponseDto;
import com.xianan.xuhui.netsecurityproject.domain.entity.User;
import com.xianan.xuhui.netsecurityproject.domain.token.WebSessionDto;
import com.xianan.xuhui.netsecurityproject.exception.BizException;
import com.xianan.xuhui.netsecurityproject.mapper.web.UserMapper;
import com.xianan.xuhui.netsecurityproject.service.web.IWeiXinService;
import com.xianan.xuhui.netsecurityproject.utils.WebTokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author xiaoli
 * @description TODO
 * @since 2025/3/25 10:51
 */
@Slf4j
@Service
public class WeiXinServiceImpl implements IWeiXinService {

    @Value("${core.wx.miniProgram.appid}")
    private String WEI_XIN_APP_ID;
    @Value("${core.wx.miniProgram.secret}")
    private String WEI_XIN_APP_SECRET;
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private WebTokenUtil webTokenUtil;
    @Resource
    private UserMapper userMapper;

    @Override
    public LoginResponseDto login(LoginInputDto loginInputDto) {
        System.out.println("获取前端传递的微信小程序code："+loginInputDto.getCode());

        JSONObject weiXinParseObj = getWeiXinAccessToken();
        String access_token = weiXinParseObj.getStr("access_token");
        String open_id=weiXinParseObj.getStr("openid");
        if (ObjectUtil.isEmpty(access_token)&&ObjectUtil.isEmpty(open_id)){
            throw new BizException("access_token获取失败，登陆失败");
        }
        String weXinCode= loginInputDto.getCode();
        String weiXinUserPhone = getWeiXinUserInfo(weXinCode, access_token);
        if (ObjectUtil.isEmpty(weiXinUserPhone)){
            throw new BizException("手机号获取失败，登陆失败");
        }
        // 根据手机号查询用户信息，如果存在则直接登录，不存在则注册用户---使用mybatisplus中的query()进行书写
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone,weiXinUserPhone);
        User userInfo = userMapper.selectOne(queryWrapper);
        if (ObjectUtil.isEmpty(userInfo)){
            throw new BizException("用户不存在，登陆失败");
        }
        WebSessionDto webSessionDto = new WebSessionDto();
        webSessionDto.setId(Long.valueOf(userInfo.getId()));
        webSessionDto.setName(userInfo.getName());
        webSessionDto.setEmail(userInfo.getEmail());
        webSessionDto.setClientType(loginInputDto.getClientType());

        String redis_token_key=webTokenUtil.generateKey(open_id);
        redisTemplate.boundValueOps("token:"+redis_token_key).set(JSONUtil.toJsonStr(webSessionDto),12, TimeUnit.HOURS);
        LoginResponseDto loginResponseDto=new LoginResponseDto();
        loginResponseDto.setName(webSessionDto.getName());
        loginResponseDto.setOpenid(webSessionDto.getOpenId());
        loginResponseDto.setUnionid(webSessionDto.getUnionid());
        loginResponseDto.setToken(webSessionDto.getToken());
        // 修改最近登录时间(后续添加)

        return loginResponseDto;
    }
    public cn.hutool.json.JSONObject getWeiXinAccessToken() {
        String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+WEI_XIN_APP_ID+"&secret="+WEI_XIN_APP_SECRET;
        String getAccessTokenResponse = restTemplate.getForObject(url, String.class);
        System.out.println("getAccessTokenResponse:"+getAccessTokenResponse);
        JSONObject parseObj = JSONUtil.parseObj(getAccessTokenResponse);
        return parseObj;
    }
    public String getWeiXinUserInfo(String weiXinCode, String weiXinAccessToken){
        String url="https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+weiXinAccessToken;
        HashMap<String, String> requestBodys = new HashMap<>();
        requestBodys.put("code",weiXinCode);
        HttpEntity<HashMap<String, String>> hashMapHttpEntity = new HttpEntity<>(requestBodys);
        ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(url, hashMapHttpEntity, String.class);
        String body = stringResponseEntity.getBody();
        JSONObject parseObj = JSONUtil.parseObj(body);
        String phoneNumber = parseObj.getJSONObject("phone_info").getStr("phoneNumber");
        return phoneNumber;
    }
}
